Датасет

Датасет содержит информацию о вакцинации против Covid-2019 в различных странах мира

Цель проекта: проанализировать данные используя визуализацию и статистические критерии, построить предсказание временного ряда

In [1]:
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
import plotly.express as px
import geopandas
import statsmodels.api as sm
from statsmodels.tsa.stattools import adfuller
from statsmodels.tsa.statespace.sarimax import SARIMAX
import scipy
from statsmodels.tsa.arima.model import ARIMA
from sklearn.metrics import mean_squared_error
from sklearn.metrics import mean_absolute_percentage_error

from itertools import product
from tqdm import tqdm

import warnings
warnings.filterwarnings("ignore", category=RuntimeWarning)
warnings.filterwarnings('ignore')

from statsmodels.graphics.tsaplots import plot_acf, plot_pacf

Первичный анализ данных

In [2]:
df = pd.read_csv('vaccinations.csv')
In [3]:
df_time = pd.read_csv('vaccinations.csv')
df_time["date"] = pd.to_datetime(df_time["date"], format = '%Y-%m-%d')
df_time = df_time.replace([np.inf, -np.inf], np.nan)
df_time = df_time.fillna(0)
In [4]:
df.head()
Out[4]:
country iso_code date total_vaccinations people_vaccinated people_fully_vaccinated daily_vaccinations_raw daily_vaccinations total_vaccinations_per_hundred people_vaccinated_per_hundred people_fully_vaccinated_per_hundred daily_vaccinations_per_million vaccines source_name source_website
0 Afghanistan AFG 2021-02-22 0.0 0.0 NaN NaN NaN 0.0 0.0 NaN NaN Oxford/AstraZeneca Government of Afghanistan https://reliefweb.int/report/afghanistan/afgha...
1 Afghanistan AFG 2021-02-23 NaN NaN NaN NaN 1367.0 NaN NaN NaN 35.0 Oxford/AstraZeneca Government of Afghanistan https://reliefweb.int/report/afghanistan/afgha...
2 Afghanistan AFG 2021-02-24 NaN NaN NaN NaN 1367.0 NaN NaN NaN 35.0 Oxford/AstraZeneca Government of Afghanistan https://reliefweb.int/report/afghanistan/afgha...
3 Afghanistan AFG 2021-02-25 NaN NaN NaN NaN 1367.0 NaN NaN NaN 35.0 Oxford/AstraZeneca Government of Afghanistan https://reliefweb.int/report/afghanistan/afgha...
4 Afghanistan AFG 2021-02-26 NaN NaN NaN NaN 1367.0 NaN NaN NaN 35.0 Oxford/AstraZeneca Government of Afghanistan https://reliefweb.int/report/afghanistan/afgha...
In [5]:
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 15666 entries, 0 to 15665
Data columns (total 15 columns):
 #   Column                               Non-Null Count  Dtype  
---  ------                               --------------  -----  
 0   country                              15666 non-null  object 
 1   iso_code                             15666 non-null  object 
 2   date                                 15666 non-null  object 
 3   total_vaccinations                   9437 non-null   float64
 4   people_vaccinated                    8754 non-null   float64
 5   people_fully_vaccinated              6502 non-null   float64
 6   daily_vaccinations_raw               7928 non-null   float64
 7   daily_vaccinations                   15465 non-null  float64
 8   total_vaccinations_per_hundred       9437 non-null   float64
 9   people_vaccinated_per_hundred        8754 non-null   float64
 10  people_fully_vaccinated_per_hundred  6502 non-null   float64
 11  daily_vaccinations_per_million       15465 non-null  float64
 12  vaccines                             15666 non-null  object 
 13  source_name                          15666 non-null  object 
 14  source_website                       15666 non-null  object 
dtypes: float64(9), object(6)
memory usage: 1.8+ MB

Описание колонок

bf country - страна. в которой была проведена вакцинация

iso_code - код страны

date - дата ввода информации

total_vaccionations - число вакцины

people_vaccinated - число сделанных прививок в данной стране

people_fully_vaccinated - число людей, прошедших полную вакцинацую (она включает обычно 2 прививки)

daily_vaccinations_raw - число вакцинаций на день записи

total_vaccinations_per_hundred - количество примененных доз вакцины на 100 человек населения

people_vaccinated_per_hundred - количество людей с иммунитетом на 100 человек населения

people_fully_vaccinated_per_hundred -количество людей, прошедших полную вацинациб на 100 человек населения

daily_vaccinations_per_million - отношение в промилях числа вацинированных и общей численностью населения

vaccines - число вакцин, используемых в данной стране

source_name - источник информации

source_website - вебсайт источника

Постановка задачи: используя даннные, проанализировать, на каком этапе вакцинации находятся страны мира, узнать, какая из стран занимает лидирующую позицию по количеству сделанных вакцин, а также по процентному соотношению вакцинированных людей (два разных понятия). Кроме того, построить прогноз общего количества сделанных вакцин ближайшую неделю

Предобработка данных

Мы имеем дело с данными, датированными с конца декабря 2020 по май 2021 года

source_name и source_website в данной задаче нас не истересуют, их можно исключить

In [6]:
df = df.drop(['source_name', 'source_website'], axis=1)

Поскольку проект связан с анализом числа стран, в которых была проведена вакцинация, удалим нулевые строки total_vaccinations

In [7]:
df = df.drop(df[df.total_vaccinations.isna()].index)

iso_code страны тоже можно исключить

In [8]:
df = df.drop(['iso_code'], axis=1)

Дальнейшая предобработка данных по исключению нанов пройдет по мере необходимости в разделах "визуальный анализ данных" и "прогнозирование временного ряда"

Визуальный анализ данных

Рассморим, что из себя представляет наш датасет. Построим для начала тепловую карту, которая дает нам информацию о связях между данными таблицы

In [9]:
people_vaccinated_not_none = df.drop(df[df.people_vaccinated.isna()].index)
In [10]:
plt.subplots(figsize=(10, 10))
sns.heatmap(people_vaccinated_not_none.corr(), annot=True)
plt.show()

Для наглядности построим интеграктивны график зависимости количества людей, прошедших полную вакцинацию для каждого из дней

In [11]:
people_fully_vaccinated_per_hundred_not_none =  df.drop(df[df.people_fully_vaccinated_per_hundred.isna()].index)
In [12]:
fig = px.line(people_fully_vaccinated_per_hundred_not_none, x="date", y="people_fully_vaccinated_per_hundred", color='country')
fig.show()

Для наглядности выведем в качестве диаграммы топ 15 стран

In [13]:
countries_total_vaccinations = df.groupby(["country",'vaccines'])['total_vaccinations','people_vaccinated','people_fully_vaccinated',
                                           'daily_vaccinations','total_vaccinations_per_hundred','people_vaccinated_per_hundred',
                                           "people_fully_vaccinated_per_hundred",'daily_vaccinations_per_million'].max().reset_index()
In [14]:
data = countries_total_vaccinations[['country','people_fully_vaccinated_per_hundred']].nlargest(15,'people_fully_vaccinated_per_hundred')
fig = px.bar(data, x = 'country',y = 'people_fully_vaccinated_per_hundred',
             title="топ 15 стран по количеству людей, прошедших полную вакцинацию показатель на 100 человек населения", 
             labels = {'country': 'страны', 'people_fully_vaccinated_per_hundred' :'показатель на 100 человек населения'})
px.xlabel = "страна"
fig.show()

Из графика видно, что лидирующие позиции по полной вакцинации населения занимают Гибралтар, Израиль и Сейшельские Острова

Стоит заметить, что информация, полученная из датасета, соответствует действительности и новостным лентам. Гибралтар первым в мире завершил вакцинацию всего взрослого населения. Также как и Израиль, который является мировым лидером по вакцинации населения

Посмотрим, какие из стран сделали наибольшее число прививок

In [15]:
top_total_vaccinations = df.groupby('country').people_vaccinated.max().sort_values(ascending=False)
total_vaccinations_f = top_total_vaccinations.dropna(axis=0).reset_index()

display(total_vaccinations_f[0:7])

plt.figure(figsize=(10, 5))
plt.title('Топ стран с наибольшим числом вакцинированного населения)')
sns.barplot(x=total_vaccinations_f.country[0:7], y=total_vaccinations_f['people_vaccinated'])
plt.ylabel('Число вакцинированных людей (млн)');
country people_vaccinated
0 United States 149462265.0
1 India 131058890.0
2 United Kingdom 34934171.0
3 Brazil 31504414.0
4 England 29232101.0
5 Germany 26220901.0
6 France 16791193.0

Хотя США занимает первое место по числу вакцинированного населения, однако доля вакцинированных людей равна 30%, однако в Индии этот показатель вообще равняется 2%. Значимую роль все-так играет предыдущий показатель

In [16]:
data = countries_total_vaccinations[['country','total_vaccinations']].nlargest(15,'total_vaccinations')
fig = px.bar(data, x = 'country',y = 'total_vaccinations',
             title="Общее число сделанных вакцинаций топ 15 стран", 
             labels = {'country': 'страны', 'total_vaccinations' :'общее число вакцинаций'})
px.xlabel = "страна"
fig.show()

Посмотрим, на каком месте находится Россия:

In [17]:
data = countries_total_vaccinations[['country','people_fully_vaccinated']].nlargest(15,'people_fully_vaccinated')
fig = px.bar(data, x = 'country',y = 'people_fully_vaccinated',
             title="топ 15 стран по количеству людей, прошедших полную вакцинацию", 
             labels = {'country': 'страны', 'people_fully_vaccinated' :'число вакцинированного населения'})
px.xlabel = "страна"
fig.show()

Можно заметить, что нет единой страны, которая бы занимала лидирующую позицию в каждом из проанализированных аспектов.

Таким образом, имеем следующие результаты:

  1. лидеры по полной вакцинации населения: Гибралтар, Израиль и Сейшельские Острова
  2. лидеры по наибольшему числу вакцинированного населения: США, Индия, Англия
  3. лидеры по общему числу сделанных вакцин: Китай, США, Индия

Следующим вопросом изучения является: какая вакцина применяется наиболее часто?

In [18]:
df= df.drop(df[df.people_fully_vaccinated.isna()].index)

Рассмотрим, какие вакцины применяются в различных странах мира

In [20]:
df['vaccines'].unique().shape
Out[20]:
(29,)

Таким образом, мы имеем дело с 34 типами вакцин

Сделаем группироку по странам

In [21]:
vaccines = df.groupby(['vaccines'])['country'].unique()
vaccines = vaccines.reset_index()
vaccines
Out[21]:
vaccines country
0 CanSino, Oxford/AstraZeneca, Pfizer/BioNTech, ... [Mexico]
1 Covaxin, Oxford/AstraZeneca [India]
2 EpiVacCorona, Sputnik V [Russia]
3 Johnson&Johnson [South Africa]
4 Johnson&Johnson, Moderna, Oxford/AstraZeneca, ... [Austria, Belgium, Czechia, France, Germany, I...
5 Johnson&Johnson, Moderna, Pfizer/BioNTech [United States]
6 Moderna, Oxford/AstraZeneca [Guatemala, Honduras]
7 Moderna, Oxford/AstraZeneca, Pfizer/BioNTech [Bulgaria, Canada, Croatia, Denmark, England, ...
8 Moderna, Oxford/AstraZeneca, Pfizer/BioNTech, ... [Hungary]
9 Moderna, Pfizer/BioNTech [Curacao, Faeroe Islands, Israel, Liechtenstei...
10 Oxford/AstraZeneca [Anguilla, Bangladesh, Dominica, Falkland Isla...
11 Oxford/AstraZeneca, Pfizer/BioNTech [Andorra, Cayman Islands, Costa Rica, Guernsey...
12 Oxford/AstraZeneca, Pfizer/BioNTech, Sinopharm... [Maldives, Moldova, Peru]
13 Oxford/AstraZeneca, Pfizer/BioNTech, Sinopharm... [United Arab Emirates]
14 Oxford/AstraZeneca, Pfizer/BioNTech, Sinopharm... [Bahrain, Lebanon, Mongolia, Montenegro, Serbia]
15 Oxford/AstraZeneca, Pfizer/BioNTech, Sinovac [Colombia, Ecuador, El Salvador, Northern Cypr...
16 Oxford/AstraZeneca, Pfizer/BioNTech, Sinovac, ... [Albania, Bosnia and Herzegovina]
17 Oxford/AstraZeneca, Sinopharm/Beijing [Morocco, Namibia, Seychelles, Sri Lanka]
18 Oxford/AstraZeneca, Sinopharm/Beijing, Sinovac [Cambodia, Dominican Republic]
19 Oxford/AstraZeneca, Sinopharm/Beijing, Sputnik V [Argentina, Bolivia, Iran]
20 Oxford/AstraZeneca, Sinovac [Azerbaijan, Brazil, Indonesia, Philippines, T...
21 Pfizer/BioNTech [Aruba, Bermuda, Cyprus, Gibraltar, Greenland,...
22 Pfizer/BioNTech, Sinopharm/Beijing [Jordan, Macao]
23 Pfizer/BioNTech, Sinovac [Chile, Hong Kong, Malaysia, Turkey]
24 Pfizer/BioNTech, Sinovac, Sputnik V [Tunisia]
25 Pfizer/BioNTech, Sputnik V [San Marino]
26 Sinopharm/Beijing [Equatorial Guinea, Gabon, Zimbabwe]
27 Sinopharm/Beijing, Sputnik V [Kyrgyzstan, Laos]
28 Sputnik V [Belarus, Guinea, Kazakhstan, Paraguay]

Для наглядности построим barplot диаграмму, которая показывает, какое количество стран применяет ту или иную вакцину, а для начала сгруппируем по странам

In [22]:
new_df = df.groupby(["country",'vaccines'])['total_vaccinations','people_vaccinated','people_fully_vaccinated',
                                           'daily_vaccinations','total_vaccinations_per_hundred','people_vaccinated_per_hundred',
                                           "people_fully_vaccinated_per_hundred",'daily_vaccinations_per_million'].max().reset_index()
In [23]:
list_of_vaccines = new_df.reset_index().groupby(['vaccines'])['country'].count().sort_values(ascending=False)
list_of_vaccines = list_of_vaccines.reset_index()

with sns.plotting_context('notebook', font_scale = 2):
    plt.figure(figsize=(20, 20))
    plt.title('Распространение вакцины')
    sns.barplot(y=list_of_vaccines.vaccines, x=list_of_vaccines.country)
    plt.ylabel(' ')

Топ 3 группы вакцин:

  • Moderna, Oxford/AstraZeneca, Pfizer/BioNTech
  • Oxford/AstraZeneca
  • Johnson&Johnson, Moderna, Oxford/AstraZeneca, Pfizer/BioNTech

Проверка статистических гипотез

Параметрический критерий

Предположим, что среднее значение прививок, сделанных в марте, будет выше среднего значения прививок, сделанных в апреле

$H_0$ среднее значение ежедневного количества прививок, сделанных в марте, равно среднему значению ежедневного количества прививок, сделанных в апреле

$H_1$ среднее значение ежедневного количества прививок, сделанных в марте, больше среднего значения ежедневного количества прививок, сделанных в апреле

In [24]:
df["date"] = pd.to_datetime(df["date"], format = '%Y-%m-%d')
df = df.replace([np.inf, -np.inf], np.nan)
df = df.fillna(0)
In [25]:
daily_data = df[['daily_vaccinations','date']].groupby('date',as_index = False).sum()
daily_data['vac_test'] = daily_data['daily_vaccinations']
In [26]:
daily_data['year'] = daily_data['date'].dt.year
daily_data['month'] = daily_data['date'].dt.month
daily_data['day'] = daily_data['date'].dt.day
In [27]:
df['month'] = df['date'].dt.month
jan_month = df[df['month'] == 1]['daily_vaccinations']
feb_month = df[df['month'] == 2]['daily_vaccinations']
march_month = df[df['month'] == 3]['daily_vaccinations']
april_month = df[df['month'] == 4]['daily_vaccinations']
may_month = df[df['month'] == 5]['daily_vaccinations']
In [28]:
scipy.stats.ttest_ind(march_month, april_month)
Out[28]:
Ttest_indResult(statistic=-1.2945884000780925, pvalue=0.19553361097594368)

p value > 0.05, значит мы отклоняем нулевую гипотезу, что соответсвует тому, что среднее значение количества ежедневных прививок, сделанных в марте. равно среднему значению ежедневного количества прививок, сделанных в апреле

А теперь сделаем то же самое сравнение для апреля и февраля, и убедимся, что средние различны

$H_0$ среднее значение ежедневного количества прививок, сделанных в феврале, равно среднему значению ежедневного количества прививок, сделанных в апреле

$H_1$ среднее значение ежедневного количества прививок, сделанных в феврале, больше среднего значения ежедневного количества прививок, сделанных в апреле

In [30]:
scipy.stats.ttest_ind(feb_month, april_month)
Out[30]:
Ttest_indResult(statistic=-4.216019164370364, pvalue=2.5476821282077717e-05)

Гипотеза $H_1$ подвтерждается

Непараметрический критерий

In [32]:
people_vaccinated_data = df.drop(df[df.people_vaccinated.isna()].index)
In [33]:
people_vaccinated_data = df.drop(df[df.total_vaccinations.isna()].index)
In [34]:
people_vaccinated_data.isna().sum()
Out[34]:
country                                0
date                                   0
total_vaccinations                     0
people_vaccinated                      0
people_fully_vaccinated                0
daily_vaccinations_raw                 0
daily_vaccinations                     0
total_vaccinations_per_hundred         0
people_vaccinated_per_hundred          0
people_fully_vaccinated_per_hundred    0
daily_vaccinations_per_million         0
vaccines                               0
month                                  0
dtype: int64

Исходя из таблицы и из таблицы корреляции, можно предположить, что число сделанных за все время вакцинаций по каждой стране равно числу людей, прошедших вакцинацию

Проверим это с помощью U-критерия Манна — Уитни

Сформулируем гипотезы:

$H_0$ - число сделанных за все время вакцинаций в каждой стране равно числу людей, прошедших полную вакцинацию

$H_1$ - число сделанных за все время вакцинаций в каждой стране отличается от числа людей, прошедших полную вакцинацию

In [35]:
scipy.stats.mannwhitneyu(people_vaccinated_data.total_vaccinations, people_vaccinated_data.people_vaccinated, alternative='two-sided')
Out[35]:
MannwhitneyuResult(statistic=22748717.5, pvalue=3.2174654668474974e-14)

p value < 0.05, значит мы отвергаем нулевую гипотезу

$H_0$ - число сделанных за все время вакцинаций в каждой стране и число людей, прошедших полную вакцинацию, имеют одинаковое распределение

$H_1$ - число сделанных за все время вакцинаций в каждой стране и число людей, прошедших полную вакцинацию, взяты из различных распределений

In [36]:
scipy.stats.ranksums(df.total_vaccinations, df.people_vaccinated)
Out[36]:
RanksumsResult(statistic=7.589258726151397, pvalue=3.217407630619516e-14)

p value < 0.05, значит мы отвергаем нулевую гипотезу

Предсказание временного ряда

In [37]:
df_pred = pd.read_csv('vaccinations.csv')
check_data = df_pred.drop(df_pred[df_pred.people_vaccinated.isna()].index)

Заполним средними значениями

In [38]:
diff = check_data.total_vaccinations.mean() - check_data.people_vaccinated.mean()
diff_per_hundred = check_data.total_vaccinations_per_hundred.mean() - check_data.people_vaccinated_per_hundred.mean()

df_pred.people_vaccinated = df_pred.people_vaccinated.fillna(df_pred.total_vaccinations - diff)
df_pred.people_vaccinated_per_hundred = df_pred.people_vaccinated_per_hundred.fillna(df_pred.total_vaccinations_per_hundred - diff_per_hundred)

df_pred.daily_vaccinations = df_pred.daily_vaccinations.fillna(0)
df_pred.daily_vaccinations_per_million = df_pred.daily_vaccinations_per_million.fillna(0)

df_pred.people_fully_vaccinated = df_pred.people_fully_vaccinated.fillna(0)
df_pred.people_fully_vaccinated_per_hundred = df_pred.people_fully_vaccinated_per_hundred.fillna(0)
df_pred.daily_vaccinations_raw = df_pred.daily_vaccinations_raw.fillna(0)

timeseries_cov = df_pred[(['date', 'total_vaccinations'])].groupby('date').sum()[4:-1]
In [39]:
timeseries_cov
Out[39]:
total_vaccinations
date
2020-12-18 1.117400e+04
2020-12-19 1.195500e+04
2020-12-20 5.763820e+05
2020-12-21 6.673010e+05
2020-12-22 1.555410e+05
... ...
2021-05-01 1.123389e+09
2021-05-02 1.156549e+09
2021-05-03 1.160679e+09
2021-05-04 1.195542e+09
2021-05-05 1.205556e+09

139 rows × 1 columns

Проверим стационарность временного ряда. Для этого воспользуемся тестом Дики- Фуллера

$H_0=\phi=0$ - процесс случайного блуждания

$H_1=\phi\neq0$ $−1<1+\phi<1$ - стационарный процесс

In [40]:
print('p-value : {}'.format(sm.tsa.stattools.adfuller(timeseries_cov)[1]))
p-value : 1.0

pvalue > 0.05. Принимаем нулевую гипотезу. Ряд нестационарный

Сделаем преобразования ряда. Для начала применим преобразование Бокса-Кокса, после чего выберем порядок дифференцирования. Дифференцированием( переход к попарным разностям его соседних значений) можно стабилизировать среднее значение ряда

In [41]:
timeseries_cov['total_vaccinations_box'], l = scipy.stats.boxcox(timeseries_cov.total_vaccinations)
In [42]:
print('p-value : {}'.format(sm.tsa.stattools.adfuller(timeseries_cov.drop(columns=['total_vaccinations']))[1]))
p-value : 0.03099720798519864
In [43]:
timeseries_cov['total_vaccinations_box_diff1int2'] = timeseries_cov.total_vaccinations_box - timeseries_cov.total_vaccinations_box.shift(2)
In [44]:
timeseries_cov['total_vaccinations_box_diff2int2'] = timeseries_cov['total_vaccinations_box_diff1int2'] - timeseries_cov['total_vaccinations_box_diff1int2'].shift(2)
In [45]:
print('p-value : {}'.format(sm.tsa.stattools.adfuller(timeseries_cov.drop(columns=['total_vaccinations', 'total_vaccinations_box', 'total_vaccinations_box_diff1int2'])[4:])[1]))
p-value : 1.4990637767785552e-07
In [46]:
# STL-декомпозиция ряда
from pylab import rcParams

rcParams['figure.figsize'] = 12, 7
sm.tsa.seasonal_decompose(timeseries_cov.total_vaccinations_box_diff2int2[4:], period=1).plot()
plt.show()
In [47]:
plt.figure(figsize=(20, 7))
ax = plt.subplot(211)
sm.graphics.tsa.plot_acf(timeseries_cov.drop(columns=['total_vaccinations', 'total_vaccinations_box', 'total_vaccinations_box_diff1int2'])[4:], 
                         lags=(len(timeseries_cov)-4)/4, ax=ax)
ax = plt.subplot(212)
sm.graphics.tsa.plot_pacf(timeseries_cov.drop(columns=['total_vaccinations', 'total_vaccinations_box', 'total_vaccinations_box_diff1int2'])[4:], 
                         lags=(len(timeseries_cov)-4)/4, ax=ax)
plt.show()
In [48]:
d = 0
D = 2
In [49]:
timeseries_cov.total_vaccinations_box
Out[49]:
date
2020-12-18      46.864479
2020-12-19      47.847847
2020-12-20     152.203450
2020-12-21     158.870288
2020-12-22     103.520243
                 ...     
2021-05-01    1357.975534
2021-05-02    1369.360188
2021-05-03    1370.761535
2021-05-04    1382.453120
2021-05-05    1385.766443
Name: total_vaccinations_box, Length: 139, dtype: float64

Сделаем прогноз на неделю вперед

In [50]:
parameters = product(np.arange(0, 3), np.arange(0, 3), np.arange(0, 3), np.arange(0, 3))
In [51]:
%%time
results = []
best_aic = float('inf')

for param in tqdm(parameters):
    try:
        model = sm.tsa.statespace.SARIMAX(timeseries_cov.total_vaccinations_box, order=(param[0], d, param[1]), 
                                          seasonal_order=(param[2], D, param[3], 2)).fit(disp=False)
    except:
        continue
    aic = model.aic
    if aic < best_aic:
        best_model = model
        best_aic = aic
        best_param = param
    results.append([param, model.aic])
    
81it [00:12,  6.60it/s]
CPU times: user 19.6 s, sys: 200 ms, total: 19.8 s
Wall time: 12.3 s

In [52]:
print(best_model.summary())
                                       SARIMAX Results                                        
==============================================================================================
Dep. Variable:                 total_vaccinations_box   No. Observations:                  139
Model:             SARIMAX(1, 0, 1)x(1, 2, [1, 2], 2)   Log Likelihood                -656.978
Date:                                Wed, 12 May 2021   AIC                           1325.956
Time:                                        20:53:53   BIC                           1343.387
Sample:                                    12-18-2020   HQIC                          1333.039
                                         - 05-05-2021                                         
Covariance Type:                                  opg                                         
==============================================================================
                 coef    std err          z      P>|z|      [0.025      0.975]
------------------------------------------------------------------------------
ar.L1         -0.7238      0.106     -6.804      0.000      -0.932      -0.515
ma.L1          0.9970      0.572      1.743      0.081      -0.124       2.118
ar.S.L2        0.2011      0.155      1.294      0.196      -0.103       0.506
ma.S.L2       -1.6554      0.114    -14.562      0.000      -1.878      -1.433
ma.S.L4        0.7135      0.121      5.902      0.000       0.477       0.950
sigma2       898.3765    519.662      1.729      0.084    -120.143    1916.896
===================================================================================
Ljung-Box (L1) (Q):                   0.38   Jarque-Bera (JB):                19.05
Prob(Q):                              0.54   Prob(JB):                         0.00
Heteroskedasticity (H):               0.30   Skew:                            -0.38
Prob(H) (two-sided):                  0.00   Kurtosis:                         4.67
===================================================================================

Warnings:
[1] Covariance matrix calculated using the outer product of gradients (complex-step).
In [53]:
def invboxcox(y, l):
    if l == 0:
        return np.exp(y)
    else:
        return np.exp(np.log(l*y+1)/l)
In [54]:
timeseries_cov['arima'] = invboxcox(best_model.fittedvalues, l)
plt.figure(figsize=(20,7))
timeseries_cov.total_vaccinations.plot()
timeseries_cov.arima.plot(color='r')
plt.xticks(rotation=45)
plt.show()
In [55]:
date = ['2021-05-'+str(x) for x in range(6, 13)]
timeseries = timeseries_cov['total_vaccinations']
pred_df = pd.DataFrame(index=date)
pred_df['total_vaccinations'] = invboxcox(best_model.predict(start=139, end=145).values, l)
timeseries = pd.concat([timeseries, pred_df])
In [56]:
timeseries.drop(columns=[0])[-7:]
Out[56]:
total_vaccinations
2021-05-6 1.214892e+09
2021-05-7 1.258314e+09
2021-05-8 1.255660e+09
2021-05-9 1.301035e+09
2021-05-10 1.300137e+09
2021-05-11 1.343613e+09
2021-05-12 1.345405e+09
In [57]:
timeseries_cov['arima'] = invboxcox(best_model.fittedvalues, l)
plt.figure(figsize=(20,7))
timeseries.total_vaccinations.plot(color='r')
timeseries_cov.total_vaccinations.plot()
plt.show()

Выводы

В работы была проанализирована актуальная ситуация, связанная с вакцинацией в различных странах мирах против коронавирусной инфекции

  1. Был проведен подготовительный анализ данных, содержащий анализ датасета, наличие в нем непригодных для поставленных целей данных, удаление колонок, содержащих нулевую статистику по сделанным прививкам

  2. Проведен визуальный анализ данных, содержащий различные типы графиков, использована библиотека seaborn. Был сделан следующий вывод:

    • лидеры по полной вакцинации населения: Гибралтар, Израиль и Сейшельские Острова лидеры по наибольшему числу вакцинированного населения: США, Индия, Англиялидеры по общему числу сделанных вакцин: Китай, США, Индия
  3. Были проверены статистические гипотезы с использованием параметрического и непараметрического критериев. Статистические критерии позволили отвергнуть гипотезу, гласившую, что число сделанных за все время вакцинаций по каждой стране равно числу людей, прошедших вакцинацию (предположение было сделано на основании таблицы, где эти значения совпадали, а также коэффициенте корреляции)

  4. Было прооведено предсказание временного ряда общего числа вакцинаций в мире на последующие 7 дней. По прогнозу был получен рост числа вакцинаций